package alp.starcode.edms.dict.service;

import alp.starcode.common.base.exception.DataNotExistException;
import alp.starcode.common.base.exception.OperateException;
import alp.starcode.common.mybatis.page.Pagination;
import alp.starcode.edms.db.dao.DictDataDao;
import alp.starcode.edms.db.dao.DictTypeDao;
import alp.starcode.edms.db.entity.DictData;
import alp.starcode.edms.db.entity.DictType;
import alp.starcode.edms.dict.model.dto.DictDataDto;
import alp.starcode.edms.dict.model.vo.DictDataVo;
import alp.starcode.edms.framework.base.BaseService;
import alp.starcode.edms.framework.handler.CurrentUserComponent;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

/**
 * 字典数据管理 业务层
 *
 * @author Clxini
 * @since 2025-01-17
 */
@Slf4j
@Service
public class DictDataService extends BaseService {

    @Resource
    private DictDataDao dictDataDao;

    @Resource
    private DictTypeDao dictTypeDao;

    @Resource
    private CurrentUserComponent currentUserComponent;

    /**
     * 分页查询字典数据列表
     *
     * @param dictTypeId   字典类型ID
     * @param dictDataName 字典数据名称
     * @param dictDataCode 字典数据编码
     * @param pagination   分页对象
     * @return 字典数据列表
     */
    public Pagination<DictDataVo> pageDictData(String dictTypeId, String dictDataName, String dictDataCode, Pagination<DictDataVo> pagination) {
        // 构建查询条件
        MPJLambdaWrapper<DictData> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.eq(DictData::getIsDeleted, false);
        queryWrapper.eq(StringUtils.hasText(dictTypeId), DictData::getDictTypeId, dictTypeId);
        queryWrapper.like(StringUtils.hasText(dictDataName), DictData::getDictDataName, dictDataName);
        queryWrapper.like(StringUtils.hasText(dictDataCode), DictData::getDictDataCode, dictDataCode);
        // 默认排序方式
        queryWrapper.orderByAsc(DictData::getSort).orderByDesc(DictData::getCreateTime);
        // 查询结果
        return dictDataDao.selectJoinListPage(pagination, DictDataVo.class, queryWrapper);
    }

    /**
     * 根据ID查询字典数据详情
     *
     * @param dictDataId 字典数据ID
     * @return 字典数据详情
     */
    public DictDataVo getDictDataById(String dictDataId) {
        // 构建查询条件
        MPJLambdaWrapper<DictData> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.eq(DictData::getDictDataId, dictDataId);
        queryWrapper.eq(DictData::getIsDeleted, false);
        // 查询结果
        return dictDataDao.selectJoinOne(DictDataVo.class, queryWrapper);
    }

    /**
     * 新增字典数据
     *
     * @param dictDataDto 字典数据信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void addDictData(DictDataDto dictDataDto) {
        // 检查字典类型是否存在
        DictType dictType = dictTypeDao.getById(dictDataDto.getDictTypeId());
        if (dictType == null || dictType.getIsDeleted()) {
            throw new DataNotExistException("字典类型不存在：[%s]", dictDataDto.getDictTypeId());
        }

        // 检查编码是否已存在
        if (checkDictDataCodeExists(dictDataDto.getDictTypeId(), dictDataDto.getDictDataCode(), null)) {
            throw new OperateException("字典数据编码已存在：[%s]", dictDataDto.getDictDataCode());
        }

        // 构建实体对象
        DictData dictData = new DictData();
        BeanUtils.copyProperties(dictDataDto, dictData);
        dictData.setDictDataId(UUID.randomUUID().toString());
        dictData.setIsDeleted(false);
        dictData.setCreateUserId(currentUserComponent.getCurrentUserId());
        dictData.setCreateUserName(currentUserComponent.getCurrentUserName());
        dictData.setCreateTime(System.currentTimeMillis());
        dictData.setUpdateUserId(currentUserComponent.getCurrentUserId());
        dictData.setUpdateUserName(currentUserComponent.getCurrentUserName());
        dictData.setUpdateTime(System.currentTimeMillis());

        // 保存数据
        boolean result = dictDataDao.save(dictData);
        if (!result) {
            throw new OperateException("新增字典数据失败");
        }
    }

    /**
     * 修改字典数据
     *
     * @param dictDataDto 字典数据信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateDictData(DictDataDto dictDataDto) {
        // 检查数据是否存在
        DictData existDictData = dictDataDao.getById(dictDataDto.getDictDataId());
        if (existDictData == null || existDictData.getIsDeleted()) {
            throw new DataNotExistException("字典数据不存在，无法修改：[%s]", dictDataDto.getDictDataId());
        }

        // 检查字典类型是否存在
        DictType dictType = dictTypeDao.getById(dictDataDto.getDictTypeId());
        if (dictType == null || dictType.getIsDeleted()) {
            throw new DataNotExistException("字典类型不存在：[%s]", dictDataDto.getDictTypeId());
        }

        // 检查编码是否已存在（排除当前记录）
        if (checkDictDataCodeExists(dictDataDto.getDictTypeId(), dictDataDto.getDictDataCode(), dictDataDto.getDictDataId())) {
            throw new OperateException("字典数据编码已存在：[%s]", dictDataDto.getDictDataCode());
        }

        // 构建实体对象
        DictData dictData = new DictData();
        BeanUtils.copyProperties(dictDataDto, dictData);
        dictData.setUpdateUserId(currentUserComponent.getCurrentUserId());
        dictData.setUpdateUserName(currentUserComponent.getCurrentUserName());
        dictData.setUpdateTime(System.currentTimeMillis());

        // 更新数据
        boolean result = dictDataDao.updateById(dictData);
        if (!result) {
            throw new OperateException("修改字典数据失败");
        }
    }

    /**
     * 删除字典数据
     *
     * @param dictDataId 字典数据ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteDictData(String dictDataId) {
        // 检查数据是否存在
        DictData existDictData = dictDataDao.getById(dictDataId);
        if (existDictData == null || existDictData.getIsDeleted()) {
            throw new DataNotExistException("字典数据不存在，无法删除：[%s]", dictDataId);
        }

        // 逻辑删除字典数据
        DictData dictData = new DictData();
        dictData.setDictDataId(dictDataId);
        dictData.setIsDeleted(true);
        dictData.setUpdateUserId(currentUserComponent.getCurrentUserId());
        dictData.setUpdateUserName(currentUserComponent.getCurrentUserName());
        dictData.setUpdateTime(System.currentTimeMillis());

        boolean result = dictDataDao.updateById(dictData);
        if (!result) {
            throw new OperateException("删除字典数据失败");
        }
    }

    /**
     * 批量删除字典数据
     *
     * @param dictDataIds 字典数据ID列表
     */
    @Transactional(rollbackFor = Exception.class)
    public void batchDeleteDictData(List<String> dictDataIds) {
        if (dictDataIds == null || dictDataIds.isEmpty()) {
            throw new OperateException("字典数据ID列表不能为空");
        }

        for (String dictDataId : dictDataIds) {
            deleteDictData(dictDataId);
        }
    }

    /**
     * 根据字典类型ID查询字典数据列表
     *
     * @param dictTypeId 字典类型ID
     * @return 字典数据列表
     */
    public List<DictDataVo> getDictDataListByTypeId(String dictTypeId) {
        // 构建查询条件
        MPJLambdaWrapper<DictData> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.eq(DictData::getDictTypeId, dictTypeId);
        queryWrapper.eq(DictData::getIsDeleted, false);
        queryWrapper.orderByAsc(DictData::getSort);
        // 查询结果
        return dictDataDao.selectJoinList(DictDataVo.class, queryWrapper);
    }

    /**
     * 根据字典类型编码查询字典数据列表
     *
     * @param dictTypeCode 字典类型编码
     * @return 字典数据列表
     */
    public List<DictDataVo> getDictDataListByTypeCode(String dictTypeCode) {
        // 先根据编码查询字典类型
        DictType dictType = dictTypeDao.getOne(
            new LambdaQueryWrapper<DictType>()
                .eq(DictType::getDictTypeCode, dictTypeCode)
                .eq(DictType::getIsDeleted, false)
        );
        
        if (dictType == null) {
            // 返回空集合
            return Collections.emptyList();
        }
        return getDictDataListByTypeId(dictType.getDictTypeId());
    }

    /**
     * 检查字典数据编码是否存在
     *
     * @param dictTypeId   字典类型ID
     * @param dictDataCode 字典数据编码
     * @param excludeId    排除的ID
     * @return 是否存在
     */
    public boolean checkDictDataCodeExists(String dictTypeId, String dictDataCode, String excludeId) {
        LambdaQueryWrapper<DictData> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DictData::getDictTypeId, dictTypeId);
        queryWrapper.eq(DictData::getDictDataCode, dictDataCode);
        queryWrapper.eq(DictData::getIsDeleted, false);
        if (StringUtils.hasText(excludeId)) {
            queryWrapper.ne(DictData::getDictDataId, excludeId);
        }
        return dictDataDao.count(queryWrapper) > 0;
    }
} 